using System;
using System.Collections;
using System.Collections.Generic;
using System.Security.Principal;
using System.Security.Cryptography;
using System.Text;
using Castle.ActiveRecord;
using NHibernate.Expression;
using Saffron.Framework.Projects;

namespace Saffron.Framework.Users
{
    [ActiveRecord]
    public class UserAccount : ActiveRecordBase, IPrincipal
    {
        private int _id;
        private string _loginName;
        private string _firstName;
        private string _lastName;
        private string _email;
        private string _passwordHash;
        private int _passwordSalt;
        private string _newPassword;
        private IIdentity _identity = new GenericIdentity("Saffron User");
        private IList _projectsCreated = new List<Project>();
        private IList _userAttributes = new List<UserAttribute>();
        private string _about;
        private IList _systemRoles = new List<SystemRole>();

        [PrimaryKey]
        public int Id
        {
            get { return _id; }
            set { _id = value; }
        }

        [Property(Unique = true, NotNull = true)]
        public string Email
        {
            get { return _email; }
            set { _email = value; }
        }


        [Property(Unique=true,NotNull=true)]
        public string LoginName
        {
            get { return _loginName; }
            set { _loginName = value; }
        }
        
        [Property(NotNull=true)]
        public string PasswordHash
        {
            get { return _passwordHash; }
            set { _passwordHash = value; }
        }

        [Property(NotNull=true)]
        public int PasswordSalt
        {
            get { return _passwordSalt; }
            set { _passwordSalt = value; }
        }

        [Property]
        public string FirstName
        {
            get { return _firstName; }
            set { _firstName = value; }
        }

        [Property]
        public string LastName
        {
            get { return _lastName; }
            set { _lastName = value; }
        }

        [Property]
        public string About
        {
            get { return _about; }
            set { _about = value; }
        }


        [HasMany(typeof(Project), Table="Project", ColumnKey="CreatedBy")]
        public IList ProjectsCreated
        {
            get { return _projectsCreated; }
            set { _projectsCreated = value; }
        }

        [HasAndBelongsToMany(typeof(UserAttribute),  Table = "UserAccountAttribute", ColumnKey="UserAccountId", ColumnRef="UserAttributeId")]
        public IList UserAttributes
        {
            get { return _userAttributes; }
            set { _userAttributes = value; }
        }

        [HasAndBelongsToMany(typeof(SystemRole), Table = "UserAccountSystemRole", ColumnKey = "UserAccountId", ColumnRef = "SystemRoleId")]
        public IList SystemRoles
        {
            get { return _systemRoles; }
            set { _systemRoles = value; }

        }

        public string NewPassword
        {
            get { return _newPassword; }
            set { _newPassword = value; }
        }

        public static UserAccount FindByPrimaryKey(int id)
        {
            return (UserAccount)FindByPrimaryKey(typeof(UserAccount), id);
        }

        public static UserAccount FindByLoginName(string loginName)
        {
            return (UserAccount)FindOne(typeof(UserAccount), new EqExpression("LoginName", loginName));
        }

        public override void Create()
        {
            if (!string.IsNullOrEmpty(NewPassword))
            {
                HashPassword();
            }
            base.Create();
        }
        protected override bool BeforeSave(System.Collections.IDictionary state)
        {
            if (!string.IsNullOrEmpty(NewPassword))
            {
                HashPassword();
            }
            return base.BeforeSave(state);
        } 

        public void HashPassword()
        {
            PasswordSalt = UserServices.GetRandomSalt();
            PasswordHash = UserServices.HashPassword(NewPassword, PasswordSalt);
       }




       #region IPrincipal Members

       public IIdentity Identity
       {
           get 
           { 
               return _identity; 
           }
       }

       public bool IsInRole(string role)
       {
           SystemRoleType roleType = (SystemRoleType)Enum.Parse(typeof(SystemRoleType), role);

           foreach (SystemRole sysRole in SystemRoles)
           {
               if (sysRole.Id == (int)roleType)
                   return true;
           }
           return false;
       }

       #endregion
   }
}
